home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / programm.ing / m2posx10.zoo / m2posix.10 / src / pstring.ipp < prev    next >
Encoding:
Modula Implementation  |  1993-11-01  |  17.3 KB  |  716 lines

  1. IMPLEMENTATION MODULE pSTRING;
  2. __IMP_SWITCHES__
  3. #ifdef HM2
  4. #ifdef __LONG_WHOLE__
  5. (*$!i+: Modul muss mit $i- uebersetzt werden! *)
  6. (*$!w+: Modul muss mit $w- uebersetzt werden! *)
  7. #else
  8. (*$!i-: Modul muss mit $i+ uebersetzt werden! *)
  9. (*$!w-: Modul muss mit $w+ uebersetzt werden! *)
  10. #endif
  11. #endif
  12. (*****************************************************************************)
  13. (* 18-Sep-93, Holger Kleinschmidt                                            *)
  14. (*****************************************************************************)
  15.  
  16. VAL_INTRINSIC
  17. CAST_IMPORT
  18.  
  19. FROM SYSTEM IMPORT
  20. (* PROC *) ADR;
  21.  
  22. FROM PORTAB IMPORT
  23. (* CONST*) NULL,
  24. (* TYPE *) UNSIGNEDWORD, SIGNEDWORD;
  25.  
  26. FROM types IMPORT
  27. (* CONST*) EOS;
  28.  
  29. FROM ctype IMPORT
  30. (* PROC *) tolower, toupper, isspace;
  31.  
  32. (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
  33.  
  34. CONST
  35. #if no_MIN_MAX
  36.   MAXCARD  = CAST(CARDINAL,-1);
  37. #else
  38.   MAXCARD  = MAX(CARDINAL);
  39. #endif
  40.   NOTFOUND = -1;
  41.  
  42. (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
  43.  
  44. PROCEDURE SLEN ((* EIN/ -- *) REF s : ARRAY OF CHAR ): CARDINAL;
  45. (*T*)
  46. #if (defined ISOM2) || (defined MM2) || (defined HM2)
  47. BEGIN
  48.  RETURN(VAL(CARDINAL,LENGTH(s)));
  49. #else
  50. VAR __REG__ i : UNSIGNEDWORD;
  51. BEGIN
  52.  i := 0;
  53.  WHILE (i <= VAL(UNSIGNEDWORD,HIGH(s))) AND (s[i] <> EOS) DO
  54.    INC(i);
  55.  END;
  56.  RETURN(VAL(CARDINAL,i));
  57. #endif
  58. END SLEN;
  59.  
  60. (*---------------------------------------------------------------------------*)
  61.  
  62. PROCEDURE ASSIGN ((* EIN/ -- *) REF src : ARRAY OF CHAR;
  63.                   (* -- /AUS *) VAR dst : ARRAY OF CHAR );
  64. (*T*)
  65. VAR __REG__ i   : UNSIGNEDWORD;
  66.     __REG__ max : UNSIGNEDWORD;
  67.  
  68. BEGIN
  69.  IF HIGH(src) > HIGH(dst) THEN
  70.    max := VAL(UNSIGNEDWORD,HIGH(dst));
  71.  ELSE
  72.    max := VAL(UNSIGNEDWORD,HIGH(src));
  73.  END;
  74.  
  75.  i := 0;
  76.  WHILE (i <= max) AND (src[i] <> EOS) DO
  77.    dst[i] := src[i];
  78.    INC(i);
  79.  END;
  80.  IF i <= VAL(UNSIGNEDWORD,HIGH(dst)) THEN
  81.    dst[i] := EOS;
  82.  END;
  83. END ASSIGN;
  84.  
  85. (*---------------------------------------------------------------------------*)
  86.  
  87. PROCEDURE CONCAT ((* EIN/ -- *) REF s1  : ARRAY OF CHAR;
  88.                   (* EIN/ -- *)     s2  : ARRAY OF CHAR;
  89.                   (* -- /AUS *) VAR dst : ARRAY OF CHAR );
  90. (*T*)
  91. VAR __REG__ i1  : SIGNEDWORD;
  92.     __REG__ i2  : SIGNEDWORD;
  93.     __REG__ max : SIGNEDWORD;
  94.  
  95. BEGIN
  96.  IF HIGH(s1) > HIGH(dst) THEN
  97.    max := VAL(SIGNEDWORD,HIGH(dst));
  98.  ELSE
  99.    max := VAL(SIGNEDWORD,HIGH(s1));
  100.  END;
  101.  
  102.  i1 := 0;
  103.  WHILE (i1 <= max) AND (s1[i1] <> EOS) DO
  104.    dst[i1] := s1[i1];
  105.    INC(i1);
  106.  END;
  107.  
  108.  IF VAL(SIGNEDWORD,HIGH(s2)) > (VAL(SIGNEDWORD,HIGH(dst)) - i1) THEN
  109.    max := VAL(SIGNEDWORD,HIGH(dst)) - i1;
  110.  ELSE
  111.    max := VAL(SIGNEDWORD,HIGH(s2));
  112.  END;
  113.  
  114.  i2 := 0;
  115.  WHILE (i2 <= max) AND (s2[i2] <> EOS) DO
  116.    dst[i1] := s2[i2];
  117.    INC(i1);
  118.    INC(i2);
  119.  END;
  120.  
  121.  IF i1 <= VAL(SIGNEDWORD,HIGH(dst)) THEN
  122.    dst[i1] := EOS;
  123.  END;
  124. END CONCAT;
  125.  
  126. (*---------------------------------------------------------------------------*)
  127.  
  128. PROCEDURE iappend (    len : CARDINAL;
  129.                    VAR app : ARRAY OF CHAR;
  130.                    VAR dst : ARRAY OF CHAR );
  131.  
  132. VAR __REG__ dIdx : UNSIGNEDWORD;
  133.     __REG__ aIdx : UNSIGNEDWORD;
  134.     __REG__ max  : UNSIGNEDWORD;
  135.  
  136. BEGIN
  137.  dIdx := VAL(UNSIGNEDWORD,SLEN(dst));
  138.  max  := VAL(UNSIGNEDWORD,HIGH(dst) + 1) - dIdx;
  139.  IF VAL(CARDINAL,max) > len THEN
  140.    max := VAL(UNSIGNEDWORD,len);
  141.  END;
  142.  IF max > VAL(UNSIGNEDWORD,HIGH(app)) THEN
  143.    max := VAL(UNSIGNEDWORD,HIGH(app) + 1);
  144.  END;
  145.  
  146.  aIdx := 0;
  147.  WHILE (aIdx < max) AND (app[aIdx] <> EOS) DO
  148.    dst[dIdx] := app[aIdx];
  149.    INC(aIdx);
  150.    INC(dIdx);
  151.  END;
  152.  
  153.  IF dIdx <= VAL(UNSIGNEDWORD,HIGH(dst)) THEN
  154.    dst[dIdx] := EOS;
  155.  END;
  156. END iappend;
  157.  
  158. (*---------------------------------------------------------------------------*)
  159.  
  160. PROCEDURE APPEND ((* EIN/ -- *) REF app : ARRAY OF CHAR;
  161.                   (* EIN/AUS *) VAR dst : ARRAY OF CHAR );
  162. (*T*)
  163. BEGIN
  164.  iappend(MAXCARD, app, dst);
  165. END APPEND;
  166.  
  167. (*---------------------------------------------------------------------------*)
  168.  
  169. PROCEDURE APPENDN ((* EIN/ -- *)     len : CARDINAL;
  170.                    (* EIN/ -- *) REF app : ARRAY OF CHAR;
  171.                    (* EIN/AUS *) VAR dst : ARRAY OF CHAR );
  172. (*T*)
  173. BEGIN
  174.  iappend(len, app, dst);
  175. END APPENDN;
  176.  
  177. (*---------------------------------------------------------------------------*)
  178.  
  179. PROCEDURE APPENDCHR ((* EIN/ -- *)     c   : CHAR;
  180.                      (* EIN/AUS *) VAR dst : ARRAY OF CHAR );
  181. (*T*)
  182. VAR __REG__ dIdx : UNSIGNEDWORD;
  183.  
  184. BEGIN
  185.  dIdx := VAL(UNSIGNEDWORD,SLEN(dst));
  186.  IF dIdx <= VAL(UNSIGNEDWORD,HIGH(dst)) THEN
  187.    dst[dIdx] := c;
  188.    IF dIdx < VAL(UNSIGNEDWORD,HIGH(dst)) THEN
  189.      dst[dIdx+1] := EOS;
  190.    END;
  191.  END;
  192. END APPENDCHR;
  193.  
  194. (*---------------------------------------------------------------------------*)
  195.  
  196. PROCEDURE COPY ((* EIN/ -- *)     from : CARDINAL;
  197.                 (* EIN/ -- *)     len  : CARDINAL;
  198.                 (* EIN/ -- *) REF src  : ARRAY OF CHAR;
  199.                 (* -- /AUS *) VAR dst  : ARRAY OF CHAR );
  200. (*T*)
  201. VAR          srcLen : CARDINAL;
  202.              cnt    : CARDINAL;
  203.      __REG__ sIdx   : UNSIGNEDWORD;
  204.      __REG__ dIdx   : SIGNEDWORD;
  205.      __REG__ max    : SIGNEDWORD;
  206.  
  207. BEGIN
  208.  srcLen := SLEN(src);
  209.  
  210.  IF (len > MAXCARD - from) OR (from + len > srcLen) THEN
  211.    IF from < srcLen THEN
  212.      cnt := srcLen - from;
  213.    ELSE
  214.      cnt := 0;
  215.    END;
  216.  ELSE
  217.    cnt := len;
  218.  END;
  219.  
  220.  IF cnt > VAL(CARDINAL,HIGH(dst)) THEN
  221.    max := VAL(SIGNEDWORD,HIGH(dst));
  222.  ELSE
  223.    max := VAL(SIGNEDWORD,cnt) - 1;
  224.  END;
  225.  
  226.  dIdx := 0;
  227.  sIdx := VAL(UNSIGNEDWORD,from);
  228.  WHILE dIdx <= max DO
  229.    dst[dIdx] := src[sIdx];
  230.    INC(dIdx);
  231.    INC(sIdx);
  232.  END;
  233.  
  234.  IF dIdx <= VAL(SIGNEDWORD,HIGH(dst)) THEN
  235.    dst[dIdx] := EOS;
  236.  END;
  237. END COPY;
  238.  
  239. (*---------------------------------------------------------------------------*)
  240.  
  241. PROCEDURE INSERT ((* EIN/ -- *)     at  : CARDINAL;
  242.                   (* EIN/ -- *)     ins : ARRAY OF CHAR;
  243.                   (* EIN/AUS *) VAR s   : ARRAY OF CHAR );
  244. (*T*)
  245. VAR         spc  : SIGNEDWORD;
  246.     __REG__ sLen : SIGNEDWORD;
  247.     __REG__ iLen : SIGNEDWORD;
  248.     __REG__ i    : SIGNEDWORD;
  249.  
  250. BEGIN
  251.  sLen := VAL(SIGNEDWORD,SLEN(s));
  252.  iLen := VAL(SIGNEDWORD,SLEN(ins));
  253.  
  254.  IF at > VAL(CARDINAL,sLen) THEN
  255.    at := VAL(CARDINAL,sLen);
  256.  END;
  257.  
  258.  spc := (VAL(SIGNEDWORD,HIGH(s) + 1) - sLen) - iLen;
  259.  
  260.  IF spc < 0 THEN
  261.    INC(sLen, spc);
  262.    IF VAL(SIGNEDWORD,HIGH(s) + 1) - VAL(SIGNEDWORD,at) < iLen THEN
  263.      iLen := VAL(SIGNEDWORD,HIGH(s) + 1) - VAL(SIGNEDWORD,at);
  264.    END;
  265.  ELSIF spc > 0 THEN
  266.    s[sLen+iLen] := EOS;
  267.  END;
  268.  
  269.  FOR i := sLen - 1 TO VAL(SIGNEDWORD,at) BY -1 DO
  270.    s[i+iLen] := s[i];
  271.  END;
  272.  
  273.  FOR i := 0 TO iLen - 1 DO
  274.    s[VAL(SIGNEDWORD,at)+i] := ins[i];
  275.  END;
  276. END INSERT;
  277.  
  278. (*---------------------------------------------------------------------------*)
  279.  
  280. PROCEDURE DELETE ((* EIN/ -- *)     from : CARDINAL;
  281.                   (* EIN/ -- *)     len  : CARDINAL;
  282.                   (* EIN/AUS *) VAR s    : ARRAY OF CHAR );
  283. (*T*)
  284. VAR __REG__ strLen : CARDINAL;
  285.  
  286. BEGIN
  287.  strLen := SLEN(s);
  288.  
  289.  IF from < MAXCARD - len THEN
  290.    INC(len, from);
  291.  ELSE
  292.    len := MAXCARD;
  293.  END;
  294.  
  295.  WHILE len < strLen DO
  296.    s[VAL(UNSIGNEDWORD,from)] := s[VAL(UNSIGNEDWORD,len)];
  297.    INC(from);
  298.    INC(len);
  299.  END;
  300.  
  301.  IF from <= VAL(CARDINAL,HIGH(s)) THEN
  302.    s[VAL(UNSIGNEDWORD,from)] := EOS;
  303.  END;
  304. END DELETE;
  305.  
  306. (*---------------------------------------------------------------------------*)
  307.  
  308. PROCEDURE LOWER ((* EIN/AUS *) VAR s : ARRAY OF CHAR );
  309. (*T*)
  310. VAR __REG__ i : UNSIGNEDWORD;
  311.  
  312. BEGIN
  313.  i := 0;
  314.  WHILE (i <= VAL(UNSIGNEDWORD,HIGH(s))) AND (s[i] <> EOS) DO
  315.    s[i] := tolower(s[i]);
  316.    INC(i);
  317.  END;
  318. END LOWER;
  319.  
  320. (*---------------------------------------------------------------------------*)
  321.  
  322. PROCEDURE UPPER ((* EIN/AUS *) VAR s : ARRAY OF CHAR );
  323. (*T*)
  324. VAR __REG__ i : UNSIGNEDWORD;
  325.  
  326. BEGIN
  327.  i := 0;
  328.  WHILE (i <= VAL(UNSIGNEDWORD,HIGH(s))) AND (s[i] <> EOS) DO
  329.    s[i] := toupper(s[i]);
  330.    INC(i);
  331.  END;
  332. END UPPER;
  333.  
  334. (*---------------------------------------------------------------------------*)
  335.  
  336. PROCEDURE compare (    len : CARDINAL;
  337.                    VAR s1  : ARRAY OF CHAR;
  338.                    VAR s2  : ARRAY OF CHAR ): INTEGER;
  339.  
  340. CONST less    = -1;
  341.       equal   =  0;
  342.       greater =  1;
  343.  
  344. VAR __REG__ i   : UNSIGNEDWORD;
  345.     __REG__ ch  : CHAR;
  346.     __REG__ max : UNSIGNEDWORD;
  347.  
  348. BEGIN
  349.  IF len = 0 THEN
  350.    RETURN(equal);
  351.  ELSE
  352.    DEC(len);
  353.  END;
  354.  IF HIGH(s1) > HIGH(s2) THEN
  355.    max := VAL(UNSIGNEDWORD,HIGH(s2));
  356.  ELSE
  357.    max := VAL(UNSIGNEDWORD,HIGH(s1));
  358.  END;
  359.  IF VAL(CARDINAL,max) > len THEN
  360.    max := VAL(UNSIGNEDWORD,len);
  361.  END;
  362.  
  363.  i := 0;
  364.  REPEAT
  365.    ch := s1[i];
  366.    IF ch <> s2[i]  THEN
  367.      IF ch < s2[i]  THEN
  368.        RETURN(less);
  369.      ELSE
  370.        RETURN(greater);
  371.      END;
  372.    ELSIF ch = EOS THEN
  373.      RETURN(equal);
  374.    END;
  375.  
  376.    INC(i);
  377.  UNTIL i > max;
  378.  
  379. (* Bis hierher waren die beiden Strings gleich *)
  380.  
  381.  IF max = VAL(UNSIGNEDWORD,len) THEN
  382.    RETURN(equal);
  383.  ELSIF HIGH(s1) < HIGH(s2) THEN
  384.    (* i <= HIGH(s2) *)
  385.    IF s2[i] = EOS THEN
  386.      RETURN(equal);
  387.    ELSE
  388.      RETURN(less);
  389.    END;
  390.  ELSIF HIGH(s1) > HIGH(s2) THEN
  391.    (* i <= HIGH(s1) *)
  392.    IF s1[i] = EOS  THEN
  393.      RETURN(equal);
  394.    ELSE
  395.      RETURN(greater);
  396.    END;
  397.  ELSE (* HIGH(s1) = HIGH(s2) *)
  398.    RETURN(equal);
  399.  END;
  400. END compare;
  401.  
  402. (*---------------------------------------------------------------------------*)
  403.  
  404. PROCEDURE EQUAL ((* EIN/ -- *) REF s1 : ARRAY OF CHAR;
  405.                  (* EIN/ -- *) REF s2 : ARRAY OF CHAR ): BOOLEAN;
  406. (*T*)
  407. BEGIN
  408.  RETURN(compare(MAXCARD, s1, s2) = 0);
  409. END EQUAL;
  410.  
  411. (*---------------------------------------------------------------------------*)
  412.  
  413. PROCEDURE EQUALN ((* EIN/ -- *)     len : CARDINAL;
  414.                   (* EIN/ -- *) REF s1  : ARRAY OF CHAR;
  415.                   (* EIN/ -- *) REF s2  : ARRAY OF CHAR ): BOOLEAN;
  416. (*T*)
  417. BEGIN
  418.  RETURN(compare(len, s1, s2) = 0);
  419. END EQUALN;
  420.  
  421. (*---------------------------------------------------------------------------*)
  422.  
  423. PROCEDURE COMPARE ((* EIN/ -- *) REF s1 : ARRAY OF CHAR;
  424.                    (* EIN/ -- *) REF s2 : ARRAY OF CHAR ): INTEGER;
  425. (*T*)
  426. BEGIN
  427.  RETURN(compare(MAXCARD, s1, s2));
  428. END COMPARE;
  429.  
  430. (*---------------------------------------------------------------------------*)
  431.  
  432. PROCEDURE COMPAREN ((* EIN/ -- *)     len : CARDINAL;
  433.                     (* EIN/ -- *) REF s1  : ARRAY OF CHAR;
  434.                     (* EIN/ -- *) REF s2  : ARRAY OF CHAR ): INTEGER;
  435. (*T*)
  436. BEGIN
  437.  RETURN(compare(len, s1, s2));
  438. END COMPAREN;
  439.  
  440. (*---------------------------------------------------------------------------*)
  441.  
  442. PROCEDURE LPOS ((* EIN/ -- *)     from : CARDINAL;
  443.                 (* EIN/ -- *) REF pat  : ARRAY OF CHAR;
  444.                 (* EIN/ -- *) REF s    : ARRAY OF CHAR ): INTEGER;
  445. (*T*)
  446. VAR         sLen  : CARDINAL;
  447.             tries : CARDINAL;
  448.     __REG__ pLen  : CARDINAL;
  449.     __REG__ pIdx  : UNSIGNEDWORD;
  450.     __REG__ start : UNSIGNEDWORD;
  451.  
  452. BEGIN
  453.  sLen := SLEN(s);
  454.  pLen := SLEN(pat);
  455.  
  456.  IF (pLen = 0) OR (pLen > sLen) OR (from > sLen - pLen) THEN
  457.    RETURN(NOTFOUND);
  458.  ELSE
  459.    tries := sLen - pLen - from;
  460.    start := VAL(UNSIGNEDWORD,from);
  461.  END;
  462.  
  463.  LOOP
  464.    pIdx := 0;
  465.    WHILE (pIdx < VAL(UNSIGNEDWORD,pLen)) AND (s[start] = pat[pIdx]) DO
  466.      INC(start);
  467.      INC(pIdx);
  468.    END;
  469.    DEC(start, pIdx);
  470.  
  471.    IF pIdx = VAL(UNSIGNEDWORD,pLen) THEN
  472.      RETURN(VAL(INTEGER,start));
  473.    ELSIF tries = 0 THEN
  474.      RETURN(NOTFOUND);
  475.    END;
  476.  
  477.    INC(start);
  478.    DEC(tries);
  479.  END;
  480. END LPOS;
  481.  
  482. (*---------------------------------------------------------------------------*)
  483.  
  484. PROCEDURE RPOS ((* EIN/ -- *)     from : CARDINAL;
  485.                 (* EIN/ -- *) REF pat  : ARRAY OF CHAR;
  486.                 (* EIN/ -- *) REF s    : ARRAY OF CHAR ): INTEGER;
  487. (*T*)
  488. VAR         sLen  : CARDINAL;
  489.     __REG__ pLen  : CARDINAL;
  490.     __REG__ pIdx  : UNSIGNEDWORD;
  491.     __REG__ start : UNSIGNEDWORD;
  492.  
  493. BEGIN
  494.  sLen  := SLEN(s);
  495.  pLen  := SLEN(pat);
  496.  
  497.  IF (pLen = 0) OR (pLen > sLen) THEN
  498.    RETURN(NOTFOUND);
  499.  END;
  500.  
  501.  IF from > sLen - pLen THEN
  502.    from := sLen - pLen;
  503.  END;
  504.  start := VAL(UNSIGNEDWORD,from);
  505.  
  506.  LOOP
  507.    pIdx := 0;
  508.    WHILE (pIdx < VAL(UNSIGNEDWORD,pLen)) AND (s[start] = pat[pIdx]) DO
  509.      INC(start);
  510.      INC(pIdx);
  511.    END;
  512.    DEC(start, pIdx);
  513.  
  514.    IF pIdx = VAL(UNSIGNEDWORD,pLen) THEN
  515.      RETURN(VAL(INTEGER,start));
  516.    ELSIF start = 0 THEN
  517.      RETURN(NOTFOUND);
  518.    END;
  519.  
  520.    DEC(start);
  521.  END;
  522. END RPOS;
  523.  
  524. (*---------------------------------------------------------------------------*)
  525.  
  526. PROCEDURE LPOSCHR ((* EIN/ -- *)     from : CARDINAL;
  527.                    (* EIN/ -- *)     c    : CHAR;
  528.                    (* EIN/ -- *) REF s    : ARRAY OF CHAR ): INTEGER;
  529. (*T*)
  530. VAR __REG__ len   : UNSIGNEDWORD;
  531.     __REG__ start : UNSIGNEDWORD;
  532.  
  533. BEGIN
  534.  len   := VAL(UNSIGNEDWORD,SLEN(s));
  535.  start := VAL(UNSIGNEDWORD,from);
  536.  
  537.  WHILE (start < len) AND (s[start] <> c) DO
  538.    INC(start);
  539.  END;
  540.  
  541.  IF start >= len THEN
  542.    RETURN(NOTFOUND);
  543.  ELSE
  544.    RETURN(VAL(INTEGER,start));
  545.  END;
  546. END LPOSCHR;
  547.  
  548. (*---------------------------------------------------------------------------*)
  549.  
  550. PROCEDURE RPOSCHR ((* EIN/ -- *)     from : CARDINAL;
  551.                    (* EIN/ -- *)     c    : CHAR;
  552.                    (* EIN/ -- *) REF s    : ARRAY OF CHAR ): INTEGER;
  553. (*T*)
  554. VAR         len   : CARDINAL;
  555.     __REG__ start : UNSIGNEDWORD;
  556.  
  557. BEGIN
  558.  len := SLEN(s);
  559.  
  560.  IF len = 0 THEN
  561.    RETURN(NOTFOUND);
  562.  ELSIF from >= len THEN
  563.    from := len - 1;
  564.  END;
  565.  start := VAL(UNSIGNEDWORD,from);
  566.  
  567.  WHILE (start > 0) AND (s[start] <> c) DO
  568.    DEC(start);
  569.  END;
  570.  
  571.  IF s[start] = c THEN
  572.    RETURN(VAL(INTEGER,start));
  573.  ELSE
  574.    RETURN(NOTFOUND);
  575.  END;
  576. END RPOSCHR;
  577.  
  578. (*---------------------------------------------------------------------------*)
  579.  
  580. PROCEDURE LPOSCHRSET ((* EIN/ -- *)     from : CARDINAL;
  581.                       (* EIN/ -- *) REF set  : ARRAY OF CHAR;
  582.                       (* EIN/ -- *) REF str  : ARRAY OF CHAR ): INTEGER;
  583. (*T*)
  584. VAR         strLen : CARDINAL;
  585.     __REG__ setIdx : UNSIGNEDWORD;
  586.     __REG__ setLen : UNSIGNEDWORD;
  587.     __REG__ c      : CHAR;
  588.  
  589. BEGIN
  590.  strLen := SLEN(str);
  591.  setLen := VAL(UNSIGNEDWORD,SLEN(set));
  592.  IF (from >= strLen) OR (setLen = 0) THEN
  593.    RETURN(NOTFOUND);
  594.  END;
  595.  
  596.  LOOP
  597.    c      := str[VAL(UNSIGNEDWORD,from)];
  598.    setIdx := 0;
  599.    WHILE (setIdx < setLen) AND (c <> set[setIdx]) DO
  600.      INC(setIdx);
  601.    END;
  602.  
  603.    IF setIdx < setLen THEN
  604.      RETURN(CAST(INTEGER,from));
  605.    ELSIF from >= strLen THEN
  606.      RETURN(NOTFOUND);
  607.    ELSE
  608.      INC(from);
  609.    END;
  610.  END;
  611. END LPOSCHRSET;
  612.  
  613. (*---------------------------------------------------------------------------*)
  614.  
  615. PROCEDURE RPOSCHRSET ((* EIN/ -- *)     from : CARDINAL;
  616.                       (* EIN/ -- *) REF set  : ARRAY OF CHAR;
  617.                       (* EIN/ -- *) REF str  : ARRAY OF CHAR ): INTEGER;
  618. (*T*)
  619. VAR         strLen : CARDINAL;
  620.     __REG__ setIdx : UNSIGNEDWORD;
  621.     __REG__ setLen : UNSIGNEDWORD;
  622.     __REG__ c      : CHAR;
  623.  
  624. BEGIN
  625.  strLen := SLEN(str);
  626.  setLen := VAL(UNSIGNEDWORD,SLEN(set));
  627.  
  628.  IF (setLen = 0) OR (strLen = 0) THEN
  629.    RETURN(NOTFOUND);
  630.  ELSIF from >= strLen THEN
  631.    from := strLen - 1;
  632.  END;
  633.  
  634.  LOOP
  635.    c      := str[VAL(UNSIGNEDWORD,from)];
  636.    setIdx := 0;
  637.    WHILE (setIdx < setLen) AND (c <> set[setIdx]) DO
  638.      INC(setIdx);
  639.    END;
  640.  
  641.    IF setIdx < setLen THEN
  642.      RETURN(CAST(INTEGER,from));
  643.    ELSIF from = 0 THEN
  644.      RETURN(NOTFOUND);
  645.    ELSE
  646.      DEC(from);
  647.    END;
  648.  END;
  649. END RPOSCHRSET;
  650.  
  651. (*---------------------------------------------------------------------------*)
  652.  
  653. PROCEDURE TOKEN ((* EIN/ -- *) REF str   : ARRAY OF CHAR;
  654.                  (* EIN/ -- *) REF stop  : ARRAY OF CHAR;
  655.                  (* EIN/AUS *) VAR idx   : CARDINAL;
  656.                  (* EIN/AUS *) VAR l1    : CARDINAL;
  657.                  (* EIN/AUS *) VAR l2    : CARDINAL;
  658.                  (* -- /AUS *) VAR token : ARRAY OF CHAR ): BOOLEAN;
  659. (*T*)
  660. VAR         end    : INTEGER;
  661.             stpLen : CARDINAL;
  662.     __REG__ min    : CARDINAL;
  663.     __REG__ max    : CARDINAL;
  664.     __REG__ strLen : CARDINAL;
  665.  
  666. BEGIN
  667.  IF l1 = 0 THEN
  668.    (* Beim ersten Aufruf muessen die Stringlaengen berechnet werden.
  669.     * Sie werden fuer spaetere Aufrufe gemerkt.
  670.     *)
  671.    l1 := SLEN(str);
  672.    l2 := SLEN(stop);
  673.  END;
  674.  strLen := l1;
  675.  stpLen := l2;
  676.  
  677.  min := idx;
  678.  IF (min >= strLen) OR (stpLen = 0) THEN
  679.    (* <str> vollstaendig durchsucht *)
  680.    token[0] := EOS;
  681.    RETURN(FALSE);
  682.  END;
  683.  
  684.  WHILE (min < strLen) AND isspace(str[VAL(UNSIGNEDWORD,min)]) DO
  685.    (* fuehrende Leerzeichen ueberlesen *)
  686.    INC(min);
  687.  END;
  688.  
  689.  (* abschliessendes Trennzeichen suchen, das fuehrende wurde schon
  690.   * beim letzten Mal ueberlesen, oder es ist das erste Token im String.
  691.   *)
  692.  end := LPOSCHRSET(min, stop, str);
  693.  IF end < 0 THEN
  694.    (* Kein Trennzeichen mehr -> jetzt kommt letztes Token, oder der
  695.     * String ist zuende.
  696.     *)
  697.    max := strLen;
  698.    idx := MAXCARD; (* beim naechsten Mal abbrechen *)
  699.  ELSE
  700.    max := CAST(CARDINAL,end);
  701.    idx := max + 1; (* beim naechsten Mal hinter dem Trenner starten *)
  702.  END;
  703.  
  704.  WHILE (max > min) AND isspace(str[VAL(UNSIGNEDWORD,max-1)]) DO
  705.    (* abschliessende Leerzeichen ueberlesen *)
  706.    DEC(max);
  707.  END;
  708.  
  709.  (* Token ohne fuehrende und abschliessende Leerzeichen abspeichern *)
  710.  COPY(min, max - min, str, token);
  711.  RETURN(TRUE);
  712. END TOKEN;
  713.  
  714. END pSTRING.
  715.  
  716.